package com.ljf.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljf.entity.Employee;
import com.ljf.entity.Menu;
import com.ljf.entity.Role;
import com.ljf.exception.BusinessException;
import com.ljf.mapper.EmployeeMapper;
import com.ljf.mapper.RoleMapper;
import com.ljf.redis.RedisKeys;
import com.ljf.redis.RedisTemplateService;
import com.ljf.service.LoginService;
import com.ljf.service.MenuService;
import com.ljf.service.RoleService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Service
public class LoginServiceImpl extends ServiceImpl<EmployeeMapper,Employee>implements LoginService {

    @Autowired
    private RedisTemplateService redisTemplateService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleService roleService;

    @Override
    public Map<String, Object> login(String username, String password, HttpServletRequest request, HttpServletResponse response) {
        //根据电话号码查询用户
        QueryWrapper  queryWrapper = new QueryWrapper<Employee>().eq("phone",username).eq("state",Employee.STATE_NORMAL);
        Employee employee = super.getOne(queryWrapper);
        if (employee == null){
            throw new BusinessException("账号不存在");
        }
        //判断用户是否被冻结
        RedisKeys disableuser = RedisKeys.DISABLEUSER;
        if (redisTemplateService.hasKey(disableuser.join(username))){
            throw new BusinessException("用户被冻结，请在"+disableuser.getTimeout()+"小时后再来登录");
        }
        //判断密码是否正确
        if (!password.equals(employee.getPassword())){
            //密码错误
            RedisKeys loginErroPwdnum = RedisKeys.LOGIN_ERRO_PWDNUM;
            int errornum = redisTemplateService.hasKey(loginErroPwdnum.join(username))?(Integer) redisTemplateService.getCacheObject(loginErroPwdnum.join(username))+1:1;
            if (errornum == 6){
                //账户要被冻结了
                redisTemplateService.setCacheObject(disableuser.join(username),true,disableuser.getTimeout(),disableuser.getTimeUnit());
                redisTemplateService.deleteObject(loginErroPwdnum.join(username));
                throw new BusinessException("账户被冻结6小时");
            }else {
                redisTemplateService.setCacheObject(loginErroPwdnum.join(username),errornum,loginErroPwdnum.getTimeout(),loginErroPwdnum.getTimeUnit());
                throw new BusinessException("账号或密码错误，还剩余"+ (6 - errornum)+"次");
            }
        }
        //登录成功
        //删除缓存中的错误的次数
        redisTemplateService.deleteObject(RedisKeys.LOGIN_ERRO_PWDNUM.join(username));
        //判断超级管理员
        if (employee.getIsAdmin()){
            List<Menu> menu = menuService.findAll();
            employee.setMenus(menu);
        }else {
            //不是超级管理员
            Set<Role> roles = roleService.queryByEid(employee.getId());
            if (roles != null && roles.size() != 0){
                employee.setRoles(roles);
                Set<Long> rids = new HashSet<>();
                for (Role role : roles){
                    rids.add(role.getId());
                }
                List<Menu> menus = menuService.queryByRids(rids);
                employee.setMenus(menus);
            }
        }
        //生成token
        String token = RedisKeys.LOGIN_USER.join(username);
        String value = JSONObject.toJSONString(employee);
        //存入redis
        redisTemplateService.setCacheObject(token,value,RedisKeys.LOGIN_USER.getTimeout(),RedisKeys.LOGIN_USER.getTimeUnit());
        //存token进cookie
        Cookie cookie = new Cookie("token",token);
        cookie.setPath("/");
        cookie.setMaxAge(7 * 24 * 60 * 60);
        response.addCookie(cookie);
        request.getSession().setAttribute("employee",employee);

        Map<String,Object> map = new HashMap<String,Object>();
        map.put("token",token);
        map.put("employee",employee);
        return map;

    }

    @Override
    public Map<String, Object> checkedToken(String token) {
        Map<String,Object> map = new HashMap<>();
        if (redisTemplateService.hasKey(token)){
            map.put("employee",JSONObject.parseObject(redisTemplateService.getCacheObject(token), Employee.class));
        }else {
            map.put("employee",null);
        }
        map.put("token",token);


        return map;
    }

    @Override
    public List<Menu> empMenu(String token) {
        //直接从缓存中获取
        String str = redisTemplateService.getCacheObject(token);
        Employee employee = JSONObject.parseObject(str, Employee.class);
        List<Menu> menus = employee.getMenus();
        return menus;
    }

    @Override
    public void exit(String token) {
        if (redisTemplateService.hasKey(token)){
            String str = redisTemplateService.getCacheObject(token);
            Employee employee = JSONObject.parseObject(str, Employee.class);
            String login_error_pwdnum = RedisKeys.LOGIN_ERRO_PWDNUM.join(employee.getUsername());
           // redisTemplateService.deleteObject(token);
           // redisTemplateService.deleteObject(login_error_pwdnum);
        }
    }


}
